#pragma once

#include "boost\lambda\lambda.hpp"

namespace ann
{
    typedef unsigned int UINT;

    //math wrap used in ann
    namespace math
    {
        using namespace boost;
        using namespace boost::lambda;

        template<class _InItr1, class _InItr2>
        inline const double EulerDis( _InItr1 _First, _InItr1 _Last, _InItr2 _Second )
        {
            double tSum = 0.0;
            //failed to find a proper way to discard result
            double* tDest = new double[std::count_if(_First, _Last, (_1, true))];

            std::transform(_First, _Last, _Second, tDest, (ref(tSum) += (_1-_2)*(_1-_2), _1));

            SAFE_DELA(tDest)

            return sqrt(tSum);
        }

        template<class _InItr1, class _InItr2>
        inline const double DotProd( _InItr1 _First, _InItr1 _Last, _InItr2 _Second )
        {
            double tSum = 0.0;
            //failed to find a proper way to discard result
            double* tDest = new double[std::count_if(_First, _Last, (_1, true))];

            std::transform(_First, _Last, _Second, tDest, (ref(tSum) += _1*_2, _1));

            SAFE_DELA(tDest)

            return tSum;
        }

        //svd decomposition
        const UINT SolveGwt( double* pG, const UINT pm, const UINT pn, double* pt, double* pw );
    }
}
